package com.platform.shiro.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;

@Configuration
public class ShiroConfiguration {
		
	/**
	 * 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的UserRealm.java
	
	@Bean
	public UserRealm userRealm() {
		return new UserRealm();
	}
	 */
	
	@Bean
	public DefaultWebSessionManager sessionManager() {
		DefaultWebSessionManager  sessionManager = new DefaultWebSessionManager();
		sessionManager.setGlobalSessionTimeout(3600000);
		sessionManager.setSessionValidationSchedulerEnabled(true);
		sessionManager.setSessionIdUrlRewritingEnabled(false);
		return sessionManager;
	}
	/**
	 * 	<!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session -->  
		<!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 -->  
		<!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->  
	 * @param sessionManager
	 * @param realm
	 * @return
	 */
	@Bean
	public  DefaultWebSecurityManager securityManager(DefaultWebSessionManager sessionManager,UserRealm realm) {
		DefaultWebSecurityManager  securityManager = new DefaultWebSecurityManager();
		securityManager.setSessionManager(sessionManager);
		securityManager.setRealm(realm);
		return securityManager;
	}
	
	
	@Bean
	public  ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
		ShiroFilterFactoryBean  shiroFilter = new ShiroFilterFactoryBean();
		//	<!-- Shiro的核心安全接口,这个属性是必须的 -->  
		shiroFilter.setSecurityManager(securityManager);
		// <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.html"页面 -->  
		shiroFilter.setLoginUrl("/login.html");
		// <!-- 登录成功后要跳转的连接 -->  
		shiroFilter.setSuccessUrl("/index.html");
		/**
		 * <!-- 用户访问未对其授权的资源时,所显示的连接 -->  
    		<!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp,然后用[玄玉]登录后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp -->  
		 */
		shiroFilter.setUnauthorizedUrl("/");
		
		
		/**
		 *   <!-- Shiro连接约束配置,即过滤链的定义 -->  
	    <!-- 此处可配合我的这篇文章来理解各个过滤连的作用http://blog.csdn.net/jadyer/article/details/12172839 -->  
	    <!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 -->  
	    <!-- anon：它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->  
	    <!-- authc：该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->  
		 */
		Map<String,String> filterChainDefinitionMap = new HashMap<String,String>();
		
		filterChainDefinitionMap.put("/statics/**", "anon");
		filterChainDefinitionMap.put("/api/**", "anon");
		filterChainDefinitionMap.put("/login.html", "anon");
		filterChainDefinitionMap.put("/sys/login", "anon");
		filterChainDefinitionMap.put("/captcha.jpg", "anon");
		filterChainDefinitionMap.put("/**", "authc");
		
		shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
		
		return shiroFilter;
		
	}

	@Bean
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}
	
	@Bean
	@DependsOn("lifecycleBeanPostProcessor")
	public DefaultAdvisorAutoProxyCreator  defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator  creator  =  new DefaultAdvisorAutoProxyCreator();
		creator.setProxyTargetClass(true);
		return creator;
	}
	
	@Bean
	public AuthorizationAttributeSourceAdvisor  duthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor  advisor  =  new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(securityManager);
		return advisor;
	}
	
	@Bean 
	public Producer producer() {
		DefaultKaptcha producer=new DefaultKaptcha();
		Properties properties = new Properties();
		properties.put("kaptcha.border", "no");
		properties.put("kaptcha.textproducer.font.color", "black");
		properties.put("kaptcha.textproducer.char.space", "4");
		properties.put("kaptcha.textproducer.char.length", "4");
		properties.put("kaptcha.textproducer.char.string", "0123456789ABCDEFGHJKLMNPQRSTUVWSYZ");
		Config config = new Config(properties);
		producer.setConfig(config);
		return producer;
	}
}
